/**
 * 
 */
package com.icarsaas.saas.component.base;

import com.icarsaas.saas.common.page.Page;
import com.icarsaas.saas.common.page.SoulPage;
import org.hibernate.Session;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.query.Query;
import org.hibernate.transform.ResultTransformer;

import javax.persistence.EntityManager;
import java.io.Serializable;
import java.util.List;

/**
 * @author admin
 * 扩展JpaRepository基类
 */
public interface MyBaseRepository<T, ID extends Serializable> {
	/**
     * 获取实体工厂管理对象
     */
    EntityManager getEntityManager();

    /**
     * 获取 Session
     */
    Session getSession();

    /**
     * 强制与数据库同步
     */
    void flush();

    /**
     * 清除缓存数据
     */
    void clear();

    // -------------- QL Query --------------

    /**
     * QL 分页查询
     *
     * @param page
     * @param qlString
     * @param parameter
     * @return
     */
    <E> Page<E> find(Page<E> page, String qlString, Object... parameter);

    /**
     * QL 查询
     *
     * @param qlString
     * @param parameter
     * @return
     */
    <E> List<E> find(String qlString, Object... parameter);

    /**
     * QL 更新
     *
     * @param qlString
     * @param parameter
     * @return
     */
    int update(String qlString, Object... parameter);

    /**
     * 创建 QL 查询对象
     *
     * @param qlString
     * @param parameter
     * @return
     */
    Query<?> createQuery(String qlString, Object... parameter);

    // -------------- SQL Query --------------

    /**
     * SQL 分页查询
     *
     * @param page
     * @param sqlString
     * @param parameter
     * @return
     */
    <E> Page<E> findBySql(Page<E> page, String sqlString, Object... parameter);

    /**
     * SQL 分页查询
     *
     * @param page
     * @param sqlString
     * @param resultClass
     * @param parameter
     * @return
     */
    <E> Page<E> findBySql(Page<E> page, String sqlString, Class<?> resultClass, Object... parameter);

    /**
     * SQL 查询
     *
     * @param sqlString
     * @param parameter
     * @return
     */
    <E> List<E> findBySql(String sqlString, Object... parameter);

    /**
     * SQL 查询
     *
     * @param sqlString
     * @param resultClass
     * @param parameter
     * @return
     */
    <E> List<E> findBySql(String sqlString, Class<?> resultClass, Object... parameter);

    /**
     * SQL 更新
     *
     * @param sqlString
     * @param parameter
     * @return
     */
    int updateBySql(String sqlString, Object... parameter);

    /**
     * 创建 SQL 查询对象
     *
     * @param sqlString
     * @param parameter
     * @return
     */
    Query<?> createSqlQuery(String sqlString, Object... parameter);

    // -------------- Criteria --------------

    /**
     * 分页查询
     *
     * @param page
     * @return
     */
    Page<T> find(Page<T> page);

    /**
     * 使用检索标准对象分页查询
     *
     * @param page
     * @param detachedCriteria
     * @return
     */
    Page<T> find(Page<T> page, DetachedCriteria detachedCriteria);

    /**
     * 使用检索标准对象分页查询
     *
     * @param page
     * @param detachedCriteria
     * @param resultTransformer
     * @return
     */
    Page<T> find(Page<T> page, DetachedCriteria detachedCriteria, ResultTransformer resultTransformer);

    /**
     * 使用检索标准对象查询
     *
     * @param detachedCriteria
     * @return
     */
    List<T> find(DetachedCriteria detachedCriteria);

    /**
     * 使用检索标准对象查询
     *
     * @param detachedCriteria
     * @param resultTransformer
     * @return
     */
    List<T> find(DetachedCriteria detachedCriteria, ResultTransformer resultTransformer);

    /**
     * 使用检索标准对象查询记录数
     *
     * @param detachedCriteria
     * @return
     */
    long count(DetachedCriteria detachedCriteria);

    /**
     * 创建与会话无关的检索标准对象
     *
     * @param criterions Restrictions.eq("name", value);
     * @return
     */
    DetachedCriteria createDetachedCriteria(Criterion... criterions);
    
    /**
     * 返回soul-table 分页数据
     * @param <E>
     * @param page
     * @param sqlString
     * @param resultClass
     * @param parameter
     * @return
     */
    public <E> SoulPage<E> findBySqlForSoul(SoulPage<E> page, String sqlString, Class<?> resultClass, Object... parameter);
}
